home *** CD-ROM | disk | FTP | other *** search
- /*
- ConvertCharSet -- ein Programm zum Konvertieren von Zeichensätzen
-
- entstanden aus
-
- Arguments -- eine CLI-Hülle für Programme ab Workbench 2.04
- */
-
- /*
- * allgemeine Include-Dateien
- */
-
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
-
- /*
- * spezielle Amiga-Include-Dateien
- */
-
- #include <dos/dos.h>
- #include <dos/dosasl.h>
- #include <dos/rdargs.h>
- #include <exec/memory.h>
- #include <exec/types.h>
- #include <exec/execbase.h>
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
-
- /*
- * Defines, die bei einer Kopie zu ändern sind
- */
-
- #define PROGNAME "ConvertCharSet" /* Default-Name des Programms */
- #define VERSION "1.5" /* Versions-Nummer 1.0 am Anfang! */
- #define AUTHOR "David Göhler" /* Name des Autors */
- #define DATE "05.08.94" /* Datum der letzten Änderung */
- #define ENVVAR PROGNAME /* Name einer ENV-Variable */
-
- /*
- * dauerhafte define's, die kaum einer Änderung bedürfen
- */
-
- #define NAMELEN 255 /* Länge des Programmnamens */
- #define LINELEN 10000 /* Zeilenlänge im Makefile */
- #define BUFLEN 200 /* Pufferlänge für Datei-Pattern */
-
- /*
- * Flags für GetNextFileName
- */
-
- #define GNF_NODIR 1 /* keine Verzeichnisse zurückgeben */
- #define GNF_ALL 2 /* auch Unterverzeichnisse */
-
- /*
- * spezielle Defines nur für dieses Programm
- */
-
- #define LF 0x0A /* linefeed */
- #define CR 0x0D /* Carriage Return */
-
- #define TABLETEMPLATE "s:%s.tab"
-
- /*
- * falls ein GCC zum Einsatz kommt, DICE-Spezialitäten abwürgen
- */
-
- #ifdef __GNUC__
- #define __stkargs /* kennt der GCC nicht */
- #endif
-
- const char VersionID []="$VER: " PROGNAME " " VERSION " - © " AUTHOR " (" DATE ")";
- const char TemplateString []="FILES/A/M,TABLE/A,EXT=EXTENSION/K,DEST=DESTINATION/K,STRIPLF/S,STRIPCR/S,LF2CR/S,CR2LF/S,QUIET/S,NOENV/S";
- enum TemplateEnum { FILES,TABLE,EXTENSION,DESTINATION,STRIPLF,STRIPCR,LF2CR,CR2LF,QUIET,NOENV };
-
- BOOL somethingfound = FALSE;
-
- typedef struct {
- char *filenames; /* Datei oder Pattern der umzuwandelnden Dateien */
- char *table; /* Convertierungstabelle */
- char *extension; /* Extension, die anzuhängen ist */
- char *destination; /* Zielname, falls gewünscht */
- LONG striplf;
- LONG stripcr;
- LONG lf2cr;
- LONG cr2lf;
- LONG quiet; /* keine Ausgaben, wenn TRUE */
- LONG noenv; /* ENV-Variable nicht auswerten wenn TRUE */
- } Template; /* Für die Kommandozeile */
-
- /*
- * globale Variablen, die die Einstellungen per Kommandozeile darstellen
- */
-
- char EnvString [BUFLEN] = ""; /* für eine eventuelle Env-Variable */
- char progname [NAMELEN]= PROGNAME; /* Für Ausgaben bei Fehlermeldungen */
- char infile [NAMELEN]= ""; /* Dateiname des Files zum Lesen */
- char inext [50] = ""; /* Extension der in-Datei */
- char outfile [NAMELEN]= ""; /* Dateiname des Files zum Schreiben*/
- char outext [50] = ""; /* Extension für out-Datei */
-
- Template CommandLineVars = { /* Template-Struktur für ReadArgs */
- 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L
- };
-
- unsigned char tt[256]; /* Translate table space*/
-
- char TempBuf[BUFLEN];
- struct RDArgs EnvArgs = {
- { EnvString, BUFLEN, 0 },
- 0, TempBuf, BUFLEN,
- 0L, // Extra Help Text, currently zero
- RDAF_NOALLOC | RDAF_NOPROMPT
- };
-
- /*
- * externe Referenzen
- */
-
- extern struct ExecBase *SysBase; /* Für den Versionstest */
-
- /*
- * Funktionen, die im folgenden erst Definiert werden
- */
-
- char *GetNextFileName(Template *, LONG);
- void initchars(char *TABLENAME, long lf2cr, long cr2lf, long quiet);
- BOOL ConvertFile(char *SrcName,char *DestName,long striplf, long stripcr);
- char *GetFileName(char *FileName,BOOL extension);
-
- /*
- * main-Kopf, für GCC-Nutzer mit Extrawurst
- */
-
- //__stkargs void _main() /* hier beginnt das Programm */
- int main(int argc, char *argv[])
- {
- struct RDArgs *rda; /* nicht notwendigerweise global */
- long rc = RETURN_OK; /* Return-Code von main */
-
- /* dies Programm läuft nur ab Version 2.04 */
- if (SysBase->LibNode.lib_Version < 37)
- { Write(Output(),"Wrong kickstart version, must 37.175 or higher\n",47);
- _exit(RETURN_FAIL);
- }
-
- /* wie heiße ich denn ? */
- if (!GetProgramName(progname,NAMELEN-1)) /* bei Fehlversuch */
- { strncpy(progname,PROGNAME,NAMELEN-1); } /* Default kopieren */
-
-
- if (CommandLineVars.noenv == FALSE)
- { // vor der KommandoZeile die ENV-Variable aus ENVVAR auswerten
- if (GetVar(ENVVAR,EnvString,BUFLEN,0) > 0)
- { // muß sein, möglicherweise ein Bug in ReadArgs
- strcat(EnvString," "); // kennt jemand dieses Problem ?
-
- EnvArgs.RDA_Source.CS_Length = strlen(EnvString);
- if (rda = ReadArgs(TemplateString,(LONG *) &CommandLineVars,&EnvArgs))
- { FreeArgs(rda); }
- }
- }
-
- /* nun die Kommandozeilenauswertung erledigen - per Systemaufruf */
- if (rda = ReadArgs (TemplateString,(LONG *) &CommandLineVars,NULL))
- {
- char *FileName = 0L; /* Zeigt auf einen Dateinamen */
- char tablename[50] = "";
-
- /*
- * Zuerst den Tabellennamen herausfinden.
- */
-
- sprintf(tablename,TABLETEMPLATE,CommandLineVars.table);
- initchars(tablename,CommandLineVars.lf2cr,
- CommandLineVars.cr2lf,
- CommandLineVars.quiet);
-
- /* CommandLineVars.filenames zeigt auf ein Array von StrPrtn */
- /* Diese werden mit einem NULL-Pointer abgeschlossen */
- /* statt diese nun per Hand auszuwerten, rufe ich mit dem */
- /* Zeiger auf CommandLineVars eine Funktion auf, die jeweils */
- /* bei einem Aufruf einen Zeiger auf einen String=Dateiname */
- /* oder NULL zurückliefert. Im NULL-Fall ist per IoErr() */
- /* auf einen Fehler zu prüfen. */
-
-
- while (FileName = GetNextFileName(&CommandLineVars,GNF_NODIR))
- {
- char *pos = 0L;
-
- somethingfound = TRUE;
-
- if (CommandLineVars.extension != 0L)
- {
- if (*CommandLineVars.extension == '.')
- { strcpy(outext,CommandLineVars.extension);
- }
- else
- { strcpy(outext,".");
- strcat(outext,CommandLineVars.extension);
- }
- }
- else
- { if (pos = strrchr(CommandLineVars.table,'2'))
- { *pos = '.';
- strcpy(outext,pos);
- *pos = '2';
- }
- else
- { strcpy(outext,".conv"); }
- }
-
- if (CommandLineVars.destination != 0L)
- { char *pos2;
- if (pos2 = strstr(pos=CommandLineVars.destination,"#?"))
- {
- strncpy(pos2,"%s",2);
- sprintf(outfile,pos,GetFileName(FileName,FALSE));
- strncpy(pos2,"#?",2);
- }
- else
- { strcpy(outfile,CommandLineVars.destination);
- }
- }
- else
- {
- if (pos = strrchr(FileName,'.'))
- { *pos = 0;
- strcpy(outfile,FileName);
- *pos = '.';
- strcat(outfile,outext);
- }
- else
- { strcpy(outfile,FileName);
- strcat(outfile,outext);
- }
- }
-
- if (!CommandLineVars.quiet)
- { printf("Converting '%s' to '%s' using '%s' ...",
- FileName,outfile,tablename);
- fflush(stdout);
- }
- if (ConvertFile(FileName,outfile,
- CommandLineVars.striplf,
- CommandLineVars.stripcr))
- { if (!CommandLineVars.quiet) puts("O.K."); }
- else
- { if (!CommandLineVars.quiet) puts("not O.K."); }
- }
-
- /* Wenn nicht alle Einträge gelesen wurde, liegt ein Fehler vor */
- if (IoErr() != ERROR_NO_MORE_ENTRIES)
- { rc = RETURN_FAIL; }
-
- /* alloziertes wieder freigeben */
- FreeArgs(rda);
- }
- else
- { rc = RETURN_ERROR; }
-
- /* bei einem Fehler, den Fehler ausgeben */
- if (rc != RETURN_OK) PrintFault(IoErr(),progname);
-
- if ((rc == RETURN_OK) && (somethingfound == FALSE))
- { rc = RETURN_WARN; }
-
- return rc;
- }
-
- BOOL IsFile(struct FileInfoBlock *fib)
- {
- return ((fib->fib_DirEntryType == ST_FILE) ||
- (fib->fib_DirEntryType == ST_LINKFILE) ||
- (fib->fib_DirEntryType == ST_SOFTLINK));
- }
-
- /*
- * für eine Funktionsbeschreibung s.o.
- *
- * all noch nicht implementiert 25. Oktober 1992
- */
-
- char *GetNextFileName(Template *CLV, LONG flags)
- {
- /* für den Vergleich, ob ich zum ersten Mal aufgerufen wurde */
- static Template lastcallCLV = {0,0,0};
- static char **arraypointer = 0; /* zeigt auf das aktuelle Pattern */
- static struct AnchorPath *AP = 0; /* Struktur für Match-Funktionen */
- static BOOL FirstTimeThisName = FALSE;
- int retcode = NULL;
-
- if (lastcallCLV != *CLV) /* erster Aufruf, alles richten */
- { arraypointer = CLV->filenames; /* Zeigt auf das erste Pattern */
- FirstTimeThisName = TRUE; /* Dieses Pattern zum ersten Mal */
- lastcallCLV = *CLV; /* jetzt gleich ! */
- if (AP != NULL) /* zeigt noch auf was ??? */
- { FreeMem(AP,sizeof(*AP)+NAMELEN); AP = NULL; }
-
- /* nun erst einmal die nötige Struktur allozieren */
- if (!(AP = AllocMem(sizeof(*AP)+NAMELEN,MEMF_PUBLIC | MEMF_CLEAR)))
- {
- SetIoErr(ERROR_NO_FREE_STORE);
- return NULL;
- }
-
- /* das System soll mir gefälligst die vollen Namen liefern */
- AP->ap_Strlen = NAMELEN;
-
- /* und auf CTRL-C soll es auch selbst aufpassen */
- AP->ap_BreakBits = SIGBREAKF_CTRL_C;
- }
-
- while (*arraypointer != NULL) /* noch ein Pattern da */
- {
- if (FirstTimeThisName) /* dann MatchFirst benutzen */
- {
- FirstTimeThisName = FALSE;
- if (!(retcode = MatchFirst(*arraypointer,AP))) /* 0 = Is OK!!!!! */
- { if (flags & GNF_NODIR)
- { if (!IsFile(&(AP->ap_Info)))
- { continue; }
- }
- return AP->ap_Buf;
- }
- else
- { SetIoErr(retcode);
- MatchEnd(AP); /* ob das sein muß ?? */
- FreeMem(AP,sizeof(*AP)+NAMELEN); AP = NULL;
- return NULL;
- }
- }
- else
- {
- if (!(retcode = MatchNext(AP))) /* 0 = Is OK!!!!! */
- { if (flags & GNF_NODIR)
- { if (!IsFile(&(AP->ap_Info)))
- { continue; }
- }
- return AP->ap_Buf;
- }
- else
- { if (retcode == ERROR_NO_MORE_ENTRIES) /* nächstes Pattern */
- { arraypointer ++;
- MatchEnd(AP); /* AP so lassen, hat ja gepaßt */
- FirstTimeThisName = TRUE;
- }
- else
- { SetIoErr(retcode);
- MatchEnd(AP); /* ob das hier sein muß ? */
- FreeMem(AP,sizeof(*AP)+NAMELEN); AP = NULL;
- return NULL;
- }
- }
- }
- }
-
- if (AP != NULL) /* zeigt noch auf was ??? */
- { FreeMem(AP,sizeof(*AP)+NAMELEN); AP = NULL; }
-
- SetIoErr(ERROR_NO_MORE_ENTRIES);
- return NULL;
- }
-
-
- void initchars(char *TABLENAME, long lf2cr, long cr2lf, long quiet)
- {
- int i;
- FILE *in;
- BOOL ok = FALSE;
-
- for (i=0; i < 256; i++)
- { tt[i] = i; }
-
- if (in = fopen(TABLENAME,"rb"))
- { if (fread(tt,256,1,in) > 0)
- { ok = TRUE; }
- else
- { if (!quiet)
- { printf("Read from '%s' failed\n",TABLENAME);
- }
- }
-
- fclose(in);
- }
- else
- { if (!quiet)
- { printf("Conversion table '%s' not found - use builtin \"Mac to Amiga\"\n",
- TABLENAME);
- }
- }
-
-
- if (! ok)
- {
- tt['ä'] = 0x8a;
- tt['ö'] = 0x9a;
- tt['ü'] = 0x9f;
- tt['ß'] = 167;
- tt['Ä'] = 0x80;
- tt['Ö'] = 0x85;
- tt['Ü'] = 0x86;
- tt['»'] = 200;
- tt['«'] = 199;
- tt['é'] = 0x8e;
- }
-
- if (lf2cr) tt[LF] = CR;
- if (cr2lf) tt[CR] = LF;
- }
-
- BOOL ConvertFile(char *SrcName,char *DestName,
- long striplf, long stripcr)
- {
- FILE *in,*out;
- BOOL retcode = FALSE;
-
- if (in = fopen(SrcName,"rb"))
- {
- if (out = fopen(DestName,"wb"))
- {
- register int inchar;
- while ((inchar = fgetc(in)) != EOF)
- {
- switch (inchar) {
- case LF: if (striplf)
- { if ((inchar = fgetc(in)) != EOF)
- { if (inchar == LF)
- { fputc(tt[LF],out); } // doppeltes Linefeed
- else
- { fputc(' ',out); // Space
- fputc(tt[inchar],out); // und den Buchstaben
- }
- }
- else
- { fputc(tt[LF],out); } // war letzter Buchstabe
- }
- else
- { fputc(tt[LF],out); }
- break;
- case CR: if (stripcr)
- { if ((inchar = fgetc(in)) != EOF)
- { if (inchar == CR)
- { fputc(tt[CR],out); } // doppeltes Linefeed
- else
- { fputc(' ',out); // Space
- fputc(tt[inchar],out); // und den Buchstaben
- }
- }
- else
- { fputc(tt[CR],out); } // war letzter Buchstabe
- }
- else
- { fputc(tt[CR],out); }
- break;
- default: fputc(tt[inchar],out);
- break;
- }
- }
- retcode = TRUE;
- fclose(out);
- }
- else
- { printf("Konnte %s nicht zum Schreiben nicht öffnen\n",DestName);
- }
- fclose(in);
- }
- else
- { printf("Konnte %s nicht zum Lesen nicht öffnen\n",SrcName);
- }
-
- return retcode;
- }
-
- char *GetFileName(char *FileName,BOOL extension)
- {
- static char buf[100];
- char *pos = 0;
- char *ext = 0;
-
- if ((pos = strrchr(FileName,'/')) == 0)
- { if ((pos = strrchr(FileName,':')) == 0)
- { pos = FileName; }
- else
- { pos++; }
- }
- else
- { pos++; }
-
- if (!extension)
- { if (ext = strrchr(FileName,'.'))
- { *ext = '\0'; }
- }
-
- strncpy(buf,pos,100);
-
- if (ext != 0L)
- { *ext = '.'; }
-
- return buf;
- }
-